#include "head.h"
int main(int argc, char *argv[]){
    //./client 172.22.123.229 1234
    //建立与服务器端连接
    ARGS_CHECK(argc, 3);
    int sockFd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(argv[2]));
    addr.sin_addr.s_addr = inet_addr(argv[1]);
    int ret = connect(sockFd, (struct sockaddr *)&addr, sizeof(addr));
    ERROR_CHECK(ret, -1, "connect1");

    //初始化命令结构体
    commond_t *mycmd=calloc(1,sizeof(commond_t));
    mycmd->sockFd = sockFd;
    strcpy(mycmd->addr,argv[1]);
    strcpy(mycmd->port,argv[2]);
    //strcpy(mycmd->token,"notoken");
    //把token发过去，这时候还是notoken
    send(sockFd,mycmd->token,1,0);//发一个0过去
    //选择登录或注册
    char rebuf[20] = {0};
    ret = recv(sockFd,rebuf,22,0);
    ERROR_CHECK(ret, -1, "inquiry 1 or 2");
    puts(rebuf);
    memset(rebuf,0,20);
    ret = read(STDIN_FILENO, rebuf, 20);
    ERROR_CHECK(ret, -1, "reply 1 or 2");
    rebuf[1]=0;//吃掉回车
    ret = send(sockFd,rebuf,20,0);
    ERROR_CHECK(ret, -1, "send 1 or 2");
    char* replyNum = rebuf;
    //选择登录
    if(strcmp(replyNum,"1")==0){
        while(1){
            char userName[20] = {0} ;
            char *password;
            char callback[20] = {0};
            printf("请输入用户名：\n");
            int ret = read(STDIN_FILENO, userName, sizeof(userName));
            ret = send(sockFd, userName, strlen(userName) - 1, 0);
            ERROR_CHECK(ret,-1,"send login usrname");
            strncpy(mycmd->usrName,userName,strlen(userName)-1);//吃掉回车
            //puts(mycmd->usrName);
            password = getpass("请输入密码：");
            //puts(password);
            ret = send(sockFd, password, strlen(password), 0);
            ERROR_CHECK(ret,-1,"send login pwd");
            //接收callback来判断是否登录成功
            ret = recv(sockFd, callback, 2, 0);
            ERROR_CHECK(ret,-1,"send login callback");
            if(atoi(callback) == 0){
                puts("Connect successfully");
                break;
            }else if(atoi(callback) == -1){
                puts("Connect failed, please try again");
            }
        }
    }else if(strcmp(replyNum,"2") == 0){//选择注册
        char buf[100] = {0};
        char userName[20] = {0} ;
        char password[100]={0};
        printf("请输入注册用户名：\n");
        ret = read(STDIN_FILENO, userName, sizeof(userName));
        ret = send(sockFd, userName, strlen(userName) - 1, 0);
        ERROR_CHECK(ret,-1,"send register usrname");
        printf("请输入注册密码：\n");
        ret = read(STDIN_FILENO, password, sizeof(password));
        ret = send(sockFd, password, strlen(password) - 1, 0);
        ERROR_CHECK(ret,-1,"send register password");
        recv(sockFd,buf,100,0);
        puts(buf);
        return 0;//注册完只能重新登录
    }else{
        memset(rebuf,0,20);//再次清零
        recv(sockFd,rebuf,20,0);
        puts(rebuf);
        return 0;
    }
    //接收第一次发来的token
    ret = recv(sockFd, mycmd->token, sizeof(mycmd->token), 0);
    ERROR_CHECK(ret,-1,"recv login token");
    //puts(mycmd->token);

    //输入指令并传输。
    char order[1024] = {0};
    int epfd = epoll_create(10);
    epollAdd(sockFd, epfd);
    epollAdd(STDIN_FILENO, epfd);
    struct epoll_event readyList[2];
    //接收命令的buf
    char buf[1024]={0};
    printf("Please input your order:\n");
    while (1)
    {   //监听socket与标准输入
        int readyNum = epoll_wait(epfd, readyList, 2, -1);
        for (int i = 0; i < readyNum; ++i)
        {
            bzero(buf,sizeof(buf));
            if(readyList[i].data.fd == sockFd){
                int ret = recv(sockFd,buf,sizeof(buf),0);
                if(ret == 0){
                    continue;
                }
                puts(buf);
            }
            if(readyList[i].data.fd==STDIN_FILENO){
                //把键盘输入读到buf里
                bzero(buf,sizeof(buf));
                int ret = read(STDIN_FILENO,buf,sizeof(buf));
                buf[strlen(buf)-1]=0;//吃掉回车
                if(ret==0){
                    return 0;//读到ctrl+d就直接退出
                }
                if(strncmp(buf,"gets",4)==0){
                    //长命令就创建一个子线程去工作 1接收 2发送
                    strcpy(mycmd->buf,buf);
                    pthread_t tid;
                    ret = pthread_create(&tid,NULL,threadFunc1,(void*)mycmd);
                    THREAD_ERROR_CHECK(ret,"pthread_create1");
                    pthread_join(tid,NULL);
                    break;
                }
                if(strncmp(buf,"puts",4)==0){
                    strcpy(mycmd->buf,buf);
                    memset(mycmd->filename,0,sizeof(mycmd->filename));
                    strcpy(mycmd->commond,strtok(buf," "));//解析获取命令
                    strcpy(mycmd->filename,strtok(NULL," "));//解析获取文件名
                    pthread_t tid;
                    ret = pthread_create(&tid,NULL,threadFunc2,(void*)mycmd);
                    THREAD_ERROR_CHECK(ret,"pthread_create2");
                    pthread_join(tid,NULL);
                    break;
                }
                //短命令就直接主线程发给服务器
                send(sockFd,buf,strlen(buf),0);
            }
        }
    }
}